<!--
 * @Description: 
 * @Version: 2.0
 * @Autor: swc
 * @Date: 2024-01-19 19:34:29
 * @LastEditors: swc
 * @LastEditTime: 2024-01-23 11:42:26
-->
<!--
 * description: 资源面版
-->
<template>
  <o-dialog-box
    :value.sync="G_isShow"
    :title="this.G_title"
    :width="this.G_width"
    @on-visible-change="onVisibleChange"
    @on-ok="onOk"
    @on-cancel="onCancel"
  >
    <div class="splitPanel" slot="content">
      <Split v-model="G_split">
        <div slot="left" class="full-width-height left-slot">
          <div class="search">
            <Input
              v-model="G_searchText"
              search
              placeholder="search"
              style="width: 100%"
              @on-search="onSearch"
              @on-enter="onEnter"
            />
          </div>
          <div class="treePanel">
            <Tree
              :data="G_treeData"
              :render="renderContent"
              @on-select-change="onSelectChange"
            ></Tree>
          </div>
        </div>

        <div slot="right" class="full-width-height right-slot">
          <div class="comp-box">
            <component
              :is="G_compConf.name"
              :config="G_compConf"
              :compBoxInfo="GT_compBoxInfo"
            />
          </div>
          <!-- <Collapse v-model="G_quickPanel" v-show="G_editIsShow">
            <Panel name="1">
              <span class="fountColor">快捷操作</span>

              <span slot="content" class="quick-button">
                <i
                  :style="itm.style"
                  class="quick-button-container quick-button-text"
                  v-for="(itm, idx) in G_quickList"
                  :key="idx"
                  :title="itm.tip"
                  @click="quickBtnClick(itm.value)"
                >
                  {{ itm.title }}
                </i>
              </span>
            </Panel>
          </Collapse> -->
          <Collapse v-model="G_quickPanel">
            <Panel name="1">
              <span class="fountColor">快捷操作</span>

              <span slot="content" class="quick-button">
                <i
                  :style="itm.style"
                  class="quick-button-container quick-button-text"
                  v-for="(itm, idx) in G_quickList"
                  :key="idx"
                  :title="itm.tip"
                  @click="quickBtnClick(itm.value)"
                >
                  {{ itm.title }}
                </i>
              </span>
            </Panel>
          </Collapse>

          <!-- <div class="full-width-height right-textarea" v-show="G_editIsShow">
            <Input
              v-model="G_content"
              maxlength="1000"
              show-word-limit
              type="textarea"
              :border="true"
              :autosize="{ minRows: 5, maxRows: 23 }"
              style="width: 100%;height:100%"
            />
            
          </div> -->
          <div class="full-width-height right-textarea">
            <code-editor
              ref="codeEditor"
              :config="G_codeEditorConf"
              @on-editor-changes="onCodeEditorChanges"
              @on-mounted="onCodeEditorMounted"
            />
          </div>
        </div>
      </Split>
    </div>
  </o-dialog-box>
</template>
<script lang="ts">
import {
  T_srv,
  Tsrv,
  ts,
  ifs,
  tvs,
  constant,
  variable,
  functions,
  ruleLib,
  I_compConf,
  quickList,
  codeEditorConf,
  vue,
  I_rule_const,
  I_rule_function,
  I_rule_var
} from './config';
import codeEditor from '../codeEditor/index.vue';

@T_srv.comp({
  components: {
    constant,
    variable,
    functions,
    ruleLib,
    codeEditor
  }
})
export default class ruleSour extends vue {
  @T_srv.prop({ type: Object, required: true }) readonly config!: any;

  @T_srv.prop({ type: Number, required: true }) readonly idx!: number;

  @T_srv.ref(`codeEditor`) G_refCodeEdirot: any;

  private GT_compBox: ifs.I_compBox;

  private G_compID: string;

  private GT_compBoxInfo: ifs.I_compBoxInfo;

  private G_split: number = 0.4;

  private G_title: string = '资源';

  // modal 显示
  private G_isShow: boolean = true;

  // 编译显示
  private G_editIsShow: boolean = false;

  // 窗口位置
  private G_screenWidth: number = document.body.clientWidth;

  private G_screenHeight: number = document.body.clientHeight;

  private G_width: string = `${this.G_screenWidth - 1000}`;

  // 树数据
  // private G_treeData: Array<any> = getTreeData();
  private G_treeData: Array<any> = [];

  // 树数据指针
  private G_treeDataMap = new Map();

  // 动态组件设置
  private G_compConf: I_compConf = { name: '', data: null };

  // 组合条件内容
  private G_content: string = '';

  // 树元素图标
  private G_treeEleIcon: string = 'ios-paper-outline';

  // 树节点图标
  private G_treeNodeIcon: string = 'ios-folder-outline';

  // 快捷按钮列表
  private G_quickList = quickList;

  // 快捷面板卡开启
  private G_quickPanel: string = '1';

  // 词典
  private G_dictionary = new Map();

  // 树动态渲染按扭参数
  private G_buttonProps: object = {
    type: 'default',
    size: 'small'
  };

  // 搜素内容
  private G_searchText: string = '';

  private G_codeEditorConf = codeEditorConf;

  private G_codeEditor: any;

  created() {
    this.G_compID = Tsrv.utils.getGUID();
    // 如果外部有传入组件信息
    if (Tsrv.utils.isEmpty(this.config?.compBoxInfo)) {
      this.GT_compBox = new ts.T_compBox(this.G_compID); // 使用本地实例
    } else {
      this.G_compID = this.config.compBoxInfo.compID;
      this.GT_compBox = this.config.compBoxInfo.TcompBox;
    }
    this.GT_compBoxInfo = { compID: this.G_compID, TcompBox: this.GT_compBox };
  }

  mounted() {}

  onCodeEditorMounted(e) {
    this.G_codeEditor = this.G_refCodeEdirot.G_editor;
    this.GT_compBox.addCompMergeName(this.G_compID, `resources`, this);
    this.getData();

    this.G_codeEditor.setValue(this.config.value);
    setTimeout(() => {
      this.G_codeEditor.refresh();
      this.G_codeEditor.doc.setCursor(this.G_codeEditor.doc.lineCount(), 0);
    }, 1);
  }

  destroyed() {
    this.GT_compBox.removeCompMergeName(this.G_compID, `resources`);
  }

  async getData() {
    interface Ires {
      id: string;
      parentID: string;
      title: string;
      expand: number;
      icon: string;
      nodeType: string;
      nodeAttr: {};
    }

    const [L_success, _, L_rows, L_msg] = await Tsrv.ruleQuery<Ires>(
      'view_rule_resources'
    );
    if (L_success) {
      this.G_treeData = Tsrv.utils.toArrayTree(L_rows, {
        parentKey: 'parentID'
      });
      this.createTreeDataMap();
    } else {
      this.$msg(L_msg);
    }

    // let constD: Array<I_rule_const> = [];
    // let varD: Array<I_rule_var> = [];
    // let functionsD: Array<I_rule_function> = [];
    // let ruleLibD: Array<{
    //   id: string;
    //   class_code: string;
    //   f_name: string;
    //   f_comment: string;
    // }> = [];
    // this.getResourcessData()
    //   .then(es => {
    //     es.forEach(([b, res, row, msg]) => {
    //       if (!Tsrv.utils.noValue(msg) || !b) {
    //         this.$msg(msg ?? res.msg);
    //       } else {
    //         row.forEach(item => {
    //           if (item?.rule_const) {
    //             constD = item.rule_const;
    //             varD = item.rule_val;
    //             functionsD = item.rule.functions;
    //           } else if (item?.f_name) {
    //             ruleLibD = item;
    //           }
    //         });
    //       }
    //       this.handleTree(constD, varD, functionsD, ruleLibD);
    //     });
    //   })
    //   .catch(e => console.error(e));
  }

  // private handleTree(
  //   constD: Array<I_rule_const>,
  //   varD: Array<I_rule_var>,
  //   functionsD: Array<I_rule_function>,
  //   ruleLibD: Array<{
  //     id: string;
  //     class_code: string;
  //     f_name: string;
  //     f_comment: string;
  //   }>
  // ) {
  //   const arr = [];
  //   this.handleConstTree(arr, constD);
  //   this.handleVarTree(arr, varD);
  //   this.handleFunctionTree(arr, functionsD);
  //   this.handleRuleLibTree(arr, ruleLibD);
  // }

  // private handleConstTree(arr: Array<any>, constD: Array<I_rule_const>) {
  //   arr.push({
  //     id: 'ruleConst',
  //     title: 'ruleConst',
  //     parentID: null,
  //     icon: 'node',
  //     nodeType: '',
  //     expand: 0,
  //     nodeAttr: null
  //   });
  //   constD.forEach(el => {
  //     if (Tsrv.utils.noValue(el.classification)) {
  //       el.classification = 'default';
  //     }
  //   });
  //   constD.sort((a, b) => {
  //     if (a.classification < b.classification) {
  //       return -1;
  //     }
  //     if (a.classification > b.classification) {
  //       return 1;
  //     }
  //     return 0;
  //   });
  //   let node = ``;
  //   constD.forEach(el => {
  //     if (node === `` || node !== el.classification) {
  //       node = el.classification;
  //       arr.push(
  //         {
  //           id: `ruleConst_${node}`,
  //           title: node,
  //           parentID: `ruleConst`,
  //           icon: 'node',
  //           nodeType: '',
  //           expand: 0,
  //           nodeAttr: null
  //         },
  //         {
  //           id: `ruleConst_${el.id}`,
  //           title: el.title,
  //           parentID: `ruleConst_${node}`,
  //           icon: 'node',
  //           nodeType: '',
  //           expand: 0,
  //           nodeAttr: null
  //         }
  //       );
  //     } else {
  //       arr.push({
  //         id: `ruleConst_${el.id}`,
  //         title: el.title,
  //         parentID: `ruleConst_${node}`,
  //         icon: 'node',
  //         nodeType: '',
  //         expand: 0,
  //         nodeAttr: null
  //       });
  //     }
  //   });
  // }

  // private handleVarTree(arr: Array<any>, varD: Array<I_rule_var>) {
  //   arr.push({
  //     id: 'ruleVar',
  //     title: 'ruleVar',
  //     parentID: null,
  //     icon: 'node',
  //     nodeType: '',
  //     expand: 0,
  //     nodeAttr: null
  //   });

  //   varD.forEach(el => {
  //     if (Tsrv.utils.noValue(el.classification)) {
  //       el.classification = 'default';
  //     }
  //   });
  //   varD.sort((a, b) => {
  //     if (a.classification < b.classification) {
  //       return -1;
  //     }
  //     if (a.classification > b.classification) {
  //       return 1;
  //     }
  //     return 0;
  //   });
  //   let node = ``;
  //   varD.forEach(el => {
  //     if (node === `` || node !== el.classification) {
  //       node = el.classification;
  //       arr.push(
  //         {
  //           id: `ruleConst_${node}`,
  //           title: node,
  //           parentID: `ruleConst`,
  //           icon: 'node',
  //           nodeType: '',
  //           expand: 0,
  //           nodeAttr: null
  //         },
  //         {
  //           id: `ruleConst_${el.id}`,
  //           title: el.title,
  //           parentID: `ruleConst_${node}`,
  //           icon: 'node',
  //           nodeType: '',
  //           expand: 0,
  //           nodeAttr: null
  //         }
  //       );
  //     } else {
  //       arr.push({
  //         id: `ruleConst_${el.id}`,
  //         title: el.title,
  //         parentID: `ruleConst_${node}`,
  //         icon: 'node',
  //         nodeType: '',
  //         expand: 0,
  //         nodeAttr: null
  //       });
  //     }
  //   });
  // }

  // private handleFunctionTree(
  //   arr: Array<any>,
  //   functionsD: Array<I_rule_function>
  // ) {
  //   arr.push({
  //     id: 'ruleFunction',
  //     title: 'ruleFunction',
  //     parentID: null,
  //     icon: 'node',
  //     nodeType: '',
  //     expand: 0,
  //     nodeAttr: null
  //   });
  // }

  // private handleRuleLibTree(
  //   arr: Array<any>,
  //   ruleLibD: Array<{
  //     id: string;
  //     class_code: string;
  //     f_name: string;
  //     f_comment: string;
  //   }>
  // ) {
  //   arr.push({
  //     id: 'ruleLib',
  //     title: 'ruleLib',
  //     parentID: null,
  //     icon: 'node',
  //     nodeType: '',
  //     nodeAttr: null
  //   });
  // }

  createTreeDataMap() {
    Tsrv.utils.addTreeKeyValue(this.G_treeData, item => {
      const L_i18nStr = `i18n.${item.title}`;
      const L_i18nTitle = this.$te(L_i18nStr)
        ? Tsrv.getI18nByPath(L_i18nStr)
        : item.title;
      // 带国际化的地图 不能直接转化对象因为编辑器要用原始Key
      this.G_treeDataMap.set(L_i18nTitle, item);
    });
  }

  /**
   * @Author: wiz
   * @param {*} P_s
   * @return {*}
   * @description: iview modal显示变化事件
   */
  onVisibleChange(P_s: boolean) {
    if (!P_s) {
      this.GT_compBox.getCompMergeName(this.G_compID, `ruleEditor`).removeModel(
        this.idx
      );
    }
  }

  /**
   * @Author: wiz
   * @param {*}
   * @return {*}
   * @description: ok按扭
   */
  onOk() {
    this.GT_compBox.getCompMergeName(
      this.G_compID,
      this.config.fromCompName
    ).setValue(this.G_codeEditor.doc.getValue());
  }
  /**
   * @Author: wiz
   * @param {*}
   * @return {*}
   * @description: 取消按扭
   */

  onCancel() {
    // this.$emit("on-cancel");
  }
  /**
   * @Author: wiz
   * @param {*} data
   * @param {*} curr
   * @return {*}
   * @description: 树选择点击改变
   */

  onSelectChange(data: any, curr: any): any {
    // nodeType 组件名
    if (curr[`nodeType`] === '') {
      return;
    }
    this.initComp();
    setTimeout(() => {
      let L_data: any;
      if (typeof curr.nodeAttr === 'string') {
        L_data = JSON.parse(curr.nodeAttr);
      } else {
        L_data = curr.nodeAttr;
      }
      if (this.G_compConf.name !== curr.nodeType) {
        this.G_compConf = {
          name: curr.nodeType,
          // compBox: this.GT_compBox,
          data: L_data
        };
      } else {
        this.GT_compBox.getCompMergeName(
          this.G_compID,
          this.G_compConf.name
        ).changeData(L_data);
      }
      // 有组件时开启编辑窗口
      if (this.G_compConf.name !== '') {
        this.G_editIsShow = true;
      }
    }, 100);
  }
  /**
   * @Author: wiz
   * @param {*}
   * @return {*}
   * @description: 回车一个要搜索树节点的事件
   */

  onEnter() {
    this.onSearch();
  }

  private findParendNode(P_id: number) {
    for (const [key, value] of this.G_treeDataMap) {
      if (value[`id`] === P_id) {
        value[`expand`] = true;
        if (value[`parentID`]) {
          this.findParendNode(value[`parentID`]);
        }
      }
    }
  }
  /**
   * @Author: wiz
   * @param {*}
   * @return {*}
   * @description: 点击搜索
   */

  onSearch() {
    for (const [key, value] of this.G_treeDataMap) {
      value[`expand`] = false;
      if (this.G_searchText === ``) {
        continue;
      }
      if (key.indexOf(this.G_searchText) > -1) {
        value[`expand`] = true;
        if (value[`parentID`]) {
          this.findParendNode(value[`parentID`]);
        }
      }
    }
  }
  /**
   * @Author: wiz
   * @param {*}
   * @return {*}
   * @description: 初始化公式编辑器
   */

  initEditor() {
    this.G_content = '';
  }
  /**
   * @Author: wiz
   * @param {*}
   * @return {*}
   * @description: 初始化组件
   */

  initComp() {
    this.G_compConf.name = '';
  }

  /**
   * @Author: wiz
   * @param {*} h
   * @param {*} root
   * @param {*} node
   * @param {*} data
   * @return {*}
   * @description: 动态渲染树方法
   */
  private renderContent(h, { root, node, data }) {
    return h(
      'span',
      {
        style: {
          display: 'inline-block',
          width: '100%'
        }
      },
      [
        h('span', [
          h('Icon', {
            props: {
              type:
                data.icon === 'node' ? this.G_treeNodeIcon : this.G_treeEleIcon
            },
            style: {
              marginRight: '8px'
            }
          }),
          h(
            'span',
            this.$te(`i18n.${data.title}`)
              ? Tsrv.getI18nByPath(`i18n.${data.title}`)
              : data.title
          )
        ]),
        h(
          'span',
          {
            style: {
              display: data.icon === 'ele' ? 'inline-block' : 'none',
              float: 'right',
              marginRight: '10px'
            }
          },
          [
            h('Button', {
              props: { ...this.G_buttonProps, icon: 'ios-add' },
              style: {
                marginRight: '6px'
              },
              on: {
                click: () => {
                  this.append(root, node, data);
                }
              }
            })
          ]
        )
      ]
    );
  }
  /**
   * @Author: wiz
   * @param {*} root
   * @param {*} node
   * @param {*} data
   * @return {*}
   * @description: 树元素增加按钮
   */

  private append(root, node, data) {
    let L_nodeAttr: any;
    // const L_v = this.G_content;

    if (typeof data.nodeAttr !== 'object') {
      L_nodeAttr = JSON.parse(data.nodeAttr);
    } else {
      L_nodeAttr = data.nodeAttr;
    }
    const L_codeText = this.getCodeText(root, data, L_nodeAttr);
    // L_codeText &&
    //  加字典,由codemirror处理
    // this.addDictionary(L_codeText.key, {
    //   tableName: L_nodeAttr.tableName,
    //   id: L_nodeAttr.id,
    //   expr: L_codeText.value
    // });
    // 直接给key i18n由各组件动态处理
    // if (L_codeText) {
    //   this.G_content = `${L_v} ${L_codeText.showPath}`;
    // }

    if (L_codeText) {
      // this.G_content = `${L_v} ${L_codeText.value}`;

      this.G_refCodeEdirot.ins(` ${L_codeText.value} `);
    }
  }

  getCodeText(root: any, data: any, P_nodeAttr: any): any {
    if (!data.nodeType) {
      return '';
    }
    let L_showPathStr: string = Tsrv.getI18nByPath(
      `i18n.${P_nodeAttr.name}`
    ).toString();

    let L_valuePathStr: string = P_nodeAttr.name;
    // 在树中查找组合路径字符串
    const findPath = (parentID: string) => {
      const L_resArr = root.filter(item => item.node.id === parentID);
      const L_title: string = L_resArr[0].node.title;
      const L_parentID: string = L_resArr[0].node.parentID;
      L_showPathStr = `${Tsrv.getI18nByPath(
        `i18n.${L_title}`
      )}.${L_showPathStr}`;
      L_valuePathStr = `${L_title}.${L_valuePathStr}`;
      L_parentID && findPath(L_parentID);
    };
    findPath(data.parentID);
    if (data.nodeType === 'constant' || data.nodeType === 'variable') {
      return {
        showPath: `${L_showPathStr}`,
        key: L_showPathStr,
        value: `${L_valuePathStr}`
      };
    }
    if (data.nodeType === 'functions' || data.nodeType === 'ruleLib') {
      return {
        showPath: `${L_showPathStr}()`,
        key: L_showPathStr,
        value: `${L_valuePathStr}()`
      };
    }
    return null;
  }

  private quickBtnClick(v: string) {
    // const L_v = this.G_content;
    // this.G_content = `${L_v} ${v} `;

    this.G_refCodeEdirot.ins(` ${v} `);
  }

  // 词法记录 key:方法库->标准方法->平均值 value:ruleFun.StandardFunction.avg
  private addDictionary(k: string, v: any) {
    this.G_dictionary.set(k, v);
  }

  private createDictionary() {}

  onCodeEditorChanges(e) {}

  // private getResourcessData() {
  //   const fields: Array<{ [key: string]: tvs.V_01 }> = [
  //     { rule_const: 1 },
  //     { rule_function: 1 },
  //     { rule_var: 1 },
  //     { _id: 0 }
  //   ];
  //   const fields1: Array<{ [key: string]: tvs.V_01 }> = [
  //     { id: 1 },
  //     { class_code: 1 },
  //     { f_name: 1 },
  //     { f_comment: 1 },
  //     { _id: 0 }
  //   ];
  //   return Promise.all([
  //     Tsrv.ruleQuery<{
  //       rule_const: Array<I_rule_const>;
  //       rule_var: Array<I_rule_var>;
  //       rule_function: Array<I_rule_function>;
  //     }>(Tsrv.globalVar.tableName.RULE_RESOURCES, fields),
  //     Tsrv.ruleQuery<{
  //       id: string;
  //       class_code: string;
  //       f_name: string;
  //       f_comment: string;
  //     }>(Tsrv.globalVar.tableName.RULE_LIB, fields1)
  //   ]);
  // }
}
</script>

<style lang="scss" scoped>
.splitPanel {
  height: 600px;
  width: 100%;
  border: 1px solid #dcdee2;
}

.treePanel {
  overflow: auto;
  padding: 6px;
}
.right-textarea {
  overflow: auto;
  border: 1px solid #f3f3f6;
}

.treePanel ::v-deep .ivu-tree-title {
  width: 95%;
}
.search {
  padding: 6px;
  border-bottom: 1px solid #dcdee2;
}
.left-slot,
.right-slot {
  display: flex;
  flex-direction: column;
}

.comp-box {
  border-bottom: 1px solid #dcdee2;
  height: 30%;
}
$quick-rows-height: 40px;
$quick-columns-width: 60px;
.quick-button {
  display: grid;
  margin-left: 6px;
  margin-top: 6px;
  grid-template-columns: repeat(auto-fill, $quick-columns-width);
  grid-template-rows: repeat(2, $quick-rows-height);
}
.fountColor {
  color: var(--default-hover-font-color);
}
.quick-button-container {
  text-align: center;
  line-height: $quick-rows-height;

  border: 1px solid #f7f7f7;
  margin: 1px;
}
.quick-button-container:hover {
  cursor: pointer;
  border: 1px solid hsl(39, 84%, 54%);
}
.quick-button-text {
  font-style: normal;
}
</style>
